package com.demo.linkList.singleLinkList;

import lombok.Data;

import java.util.Optional;
import java.util.Stack;

@Data
public class SingleLinkList {

    private Node head = new Node(0, "", "");

    /**
     * 不考虑插入的顺序
     * @param node
     */
    public void addNode(Node node) {
        // 因为head是不能动的，所以需要借助一个临时变量
        Node temp = head;
        while (true) {
            if (temp.getNextNode() == null) {
                break;
            }
            temp = temp.getNextNode();
        }
        temp.setNextNode(node);
    }

    /**
     * 按顺序插入
     * @param node
     */
    public void addSortNode(Node node) {
        Node temp = head;
        boolean isExist = false;
        while (true) {
            if (temp.getNextNode() == null) {
                break;
            }
            // 对应的序号已经存在
            if (temp.getNo().equals(node.getNo())) {
                isExist = true;
                break;
            }
            if (temp.getNextNode().getNo() > node.getNo()) {
                break;
            }
            temp = temp.getNextNode();
        }
        if (isExist) {
            System.out.println("插入的序号 " + node.getNo() + " 已存在");
        } else {
            node.setNextNode(temp.getNextNode());
            temp.setNextNode(node);
        }
    }

    /**
     * 更新节点
     * @param node
     */
    public void updateNode(Node node) {
        if (head.getName().equals("")) {
            System.out.println("链表为空");
        }
        Node temp = head.getNextNode();
        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.getNo() == node.getNo()) {
                break;
            }
            temp = temp.getNextNode();
        }
        if (temp == null || temp.getNo() != node.getNo()) {
            System.out.println("没有找到对应的节点");
        } else {
            temp.setName(node.getName());
            temp.setNickName(node.getNickName());
        }
    }

    /**
     * 删除节点
     * @param no
     */
    public void deleteNode(Integer no) {
        if (head.getNextNode() == null) {
            System.out.println("链表为空");
        }
        Node temp = head;
        while (true) {
            if (temp.getNextNode() == null) {
                break;
            }
            if (temp.getNextNode().getNo() == no) {
                break;
            }
            temp = temp.getNextNode();
        }
        if (temp.getNextNode() == null) {
            System.out.println("未找到节点");
            return;
        }
        temp.setNextNode(temp.getNextNode().getNextNode());
    }

    /**
     * 有效节点的个数
     * @return
     */
    public Integer getListNodeConunt() {
        if (head.getNextNode() == null) {
            return 0;
        }
        Node temp = head.getNextNode();
        Integer count = 0;
        while (true) {
            if (temp == null) {
                break;
            }
            count++;
            temp = temp.getNextNode();
        }
        return count;
    }

    /**
     * 获得倒数{}的节点
     * @param index
     * @return
     */
    public Node getLastNode(SingleLinkList list, Integer index) {
        Integer count = list.getListNodeConunt();
        if (Optional.of(list).isEmpty()) {
            return null;
        }
        // 第几个元素
        Integer indexPosition = 0;
        Node temp = head.getNextNode();
        while (true) {
            if (temp == null) {
                break;
            }
            // 因为链表是单向的，只能从前往后找，倒数第几个=总数-倒数的数
            if (indexPosition == (count - index)) {
                return temp;
            }
            indexPosition++;
            temp = temp.getNextNode();
        }
        return null;
    }

    /**
     * 链表反转
     * @param head
     * @return
     */
    public void getReverseList(Node head) {
        // 如果当前链表为空，或者只有一个节点，无需反转，直接返回
        if (head.getNextNode() == null || head.getNextNode().getNextNode() == null) {
            return;
        }
        // 定义一个辅助变量，帮助遍历原来的链表
        Node cur = head.getNextNode();
        // 指向当前节点cur的下一个节点
        Node next = null;
        Node reverseHead = new Node(0, "", "");
        // 遍历原来的链表，每遍历一个节点，就将其取出，并放在新的链表reverseHead的最前端
        while (cur != null) {
            // 先暂时保存当前节点的下一个节点，因为后面需要使用
            next = cur.getNextNode();
            // 将cur的下一个节点指向新的链表的最前端
            cur.setNextNode(reverseHead.getNextNode());
            reverseHead.setNextNode(cur);
            // 让cur后移
            cur = next;
        }
        // 将head.next 指向reverseHead.next，实现单链表的反转
        head.setNextNode(reverseHead.getNextNode());
    }

    /**
     * 逆序打印链表
     * @param head
     */
    public void reversePrint(Node head) {
        if (head.getNextNode() == null) {
            return;
        }
        // 创建一个栈，将各个节点压入栈
        Stack<Node> stack = new Stack<>();
        Node cur = head.getNextNode();
        while (cur != null) {
            stack.push(cur);
            cur = cur.getNextNode();
        }
        while (stack.size() > 0) {
            System.out.println(stack.pop());
        }
    }

    public void showLinkList() {
        if (head.getNextNode() == null) {
            System.out.println("链表为空");
            return;
        }
        Node temp = head.getNextNode();
        while (true) {
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.getNextNode();
        }
    }
}
